package com.archetypus.projectschedule.core.people.sf;

import javax.transaction.UserTransaction;

import com.archetypus.projectschedule.common.ServiceLocator;
import com.archetypus.projectschedule.common.ServiceLocatorException;
import com.archetypus.projectschedule.common.data.DAOFactory;
import com.archetypus.projectschedule.common.data.people.PersonDAO;
import com.archetypus.projectschedule.common.dto.people.Person;
import com.archetypus.projectschedule.common.dto.people.PersonListHandler;
import com.archetypus.projectschedule.common.exceptions.ProjectSchedulerException;

public class PersonSF implements IPersonSF {
	
	private static PersonSF instance;
	
	protected PersonSF(){}
	
	public static PersonSF getInstance(){
		if(instance == null)
			instance = new PersonSF();
		
		return instance;
	}
	
	@Override
	public void createPerson(Person person) throws ProjectSchedulerException {
		UserTransaction userTransaction = null;
		
		try {
			userTransaction = ServiceLocator.getInstance().lookupUserTransaction();
		} catch (ServiceLocatorException e) {
			e.printStackTrace();
			throw new ProjectSchedulerException("Could not create transaction object",e);
		}
		
		try {
			userTransaction.begin();
			DAOFactory daoFactory = DAOFactory.getDAOFactory();
			PersonDAO personDAO = daoFactory.getPersonDAO();
			personDAO.insert(person);
			userTransaction.commit();
		} catch (Exception e) {
			try{
				userTransaction.rollback();
			}catch(Exception ex){
				ex.printStackTrace();
				throw new ProjectSchedulerException("Could not rollback transaction",ex);
			}
			e.printStackTrace();
			throw new ProjectSchedulerException(e.getMessage(),e);
		}

	}

	@Override
	public void deletePerson(Person person) throws ProjectSchedulerException {
		UserTransaction userTransaction = null;
		
		try {
			userTransaction = ServiceLocator.getInstance().lookupUserTransaction();
		} catch (ServiceLocatorException e) {
			e.printStackTrace();
			throw new ProjectSchedulerException("Could not create transaction object",e);
		}
		
		try {
			userTransaction.begin();
			DAOFactory daoFactory = DAOFactory.getDAOFactory();
			PersonDAO personDAO = daoFactory.getPersonDAO();
			personDAO.delete(person);
			userTransaction.commit();
		} catch (Exception e) {
			try{
				userTransaction.rollback();
			}catch(Exception ex){
				ex.printStackTrace();
				throw new ProjectSchedulerException("Could not rollback transaction",ex);
			}
			e.printStackTrace();
			throw new ProjectSchedulerException(e.getMessage(),e);
		}

	}

	@Override
	public Person findPerson(Person person) throws ProjectSchedulerException {
		UserTransaction userTransaction = null;
		Person retrievedPerson = null;
		
		try {
			userTransaction = ServiceLocator.getInstance().lookupUserTransaction();
		} catch (ServiceLocatorException e) {
			e.printStackTrace();
			throw new ProjectSchedulerException("Could not create transaction object",e);
		}
		
		try {
			userTransaction.begin();
			DAOFactory daoFactory = DAOFactory.getDAOFactory();
			PersonDAO personDAO = daoFactory.getPersonDAO();
			retrievedPerson = personDAO.find(person);
			userTransaction.commit();
		} catch (Exception e) {
			try{
				userTransaction.rollback();
			}catch(Exception ex){
				ex.printStackTrace();
				throw new ProjectSchedulerException("Could not rollback transaction",ex);
			}
			e.printStackTrace();
			throw new ProjectSchedulerException(e.getMessage(),e);
		}
		return retrievedPerson;
	}

	@Override
	public PersonListHandler listPeople() throws ProjectSchedulerException {
		UserTransaction userTransaction = null;
		PersonListHandler listHandler = new PersonListHandler();
		
		try {
			userTransaction = ServiceLocator.getInstance().lookupUserTransaction();
		} catch (ServiceLocatorException e) {
			e.printStackTrace();
			throw new ProjectSchedulerException("Could not create transaction object",e);
		}
		
		try {
			userTransaction.begin();
			DAOFactory daoFactory = DAOFactory.getDAOFactory();
			PersonDAO personDAO = daoFactory.getPersonDAO();
			listHandler.setList(personDAO.list());
			userTransaction.commit();
		} catch (Exception e) {
			try{
				userTransaction.rollback();
			}catch(Exception ex){
				ex.printStackTrace();
				throw new ProjectSchedulerException("Could not rollback transaction",ex);
			}
			e.printStackTrace();
			throw new ProjectSchedulerException(e.getMessage(),e);
		}
		return listHandler;
	}

	@Override
	public void updatePerson(Person person) throws ProjectSchedulerException {
		UserTransaction userTransaction = null;
		
		try {
			userTransaction = ServiceLocator.getInstance().lookupUserTransaction();
		} catch (ServiceLocatorException e) {
			e.printStackTrace();
			throw new ProjectSchedulerException("Could not create transaction object",e);
		}
		
		try {
			userTransaction.begin();
			DAOFactory daoFactory = DAOFactory.getDAOFactory();
			PersonDAO personDAO = daoFactory.getPersonDAO();
			personDAO.update(person);
			userTransaction.commit();
		} catch (Exception e) {
			try{
				userTransaction.rollback();
			}catch(Exception ex){
				ex.printStackTrace();
				throw new ProjectSchedulerException("Could not rollback transaction",e);
			}
			e.printStackTrace();
			throw new ProjectSchedulerException(e.getMessage(),e);
		}

	}

}
